package com.kinyx.framework.reflect;

import java.util.Date;
import java.util.function.Function;

import com.kinyx.framework.Configs;
import com.kinyx.framework.bean.DKHashMap;
import com.kinyx.framework.utils.KDateTimeUtils;
import com.kinyx.framework.utils.KNumberUtils;

/**
 * 类型转换器默认实现
 * <pre>
 * 	基本类型经过调用与返回，都将被Java自动装箱，所以转换器不需要进行基本类型的处理。
 * 	转换器方法已经处理了源对象的null值情况，所以转换器不需要处理源对象null值的情况。
 * </pre>
 */
class TypeConverters {

	/** 转换器列表 */
	static final DKHashMap<Object, Object, Function<?, ?>> converters = new DKHashMap<>();

	/** 相同类型转换器，直接返回原对象。（集合类型不适用） */
	private static Function<Object, Object> SAME = (Function<Object, Object>) o -> { return o; };
	/** 数字型转字符型 */
	private static Function<Number, Character> NumberToCharacter = (Function<Number, Character>) number -> { return (char) number.intValue(); };
	/** 字符串型转布尔型 */
	private static Function<String, Boolean> StringToBoolean = (Function<String, Boolean>) str -> {
		for (final String value : Configs.default_trues) { if (str.equals(value)) { return true; } }
		for (final String value : Configs.default_falses) { if (str.equals(value)) { return false; } }
		return null;
	};

	// =================================================== 1、布尔型 =================================================== //
	static {
		converters
				// 1.1、布尔型转布尔型
				.put(Boolean.class, Boolean.class, SAME)//

				// 1.2、字符型转布尔型
				.put(Character.class, Boolean.class, (Function<Character, Boolean>) c -> { return new Integer(c).intValue() > 0; })//

				// 1.3、数字型转布尔型
				.put(Byte.class, Boolean.class, (Function<Byte, Boolean>) n -> { return n > 0; })//
				.put(Short.class, Boolean.class, (Function<Short, Boolean>) n -> { return n > 0; })//
				.put(Integer.class, Boolean.class, (Function<Integer, Boolean>) n -> { return n > 0; })//
				.put(Long.class, Boolean.class, (Function<Long, Boolean>) n -> { return n > 0; })//
				.put(Float.class, Boolean.class, (Function<Float, Boolean>) n -> { return n > 0; })//
				.put(Double.class, Boolean.class, (Function<Double, Boolean>) n -> { return n > 0; })//

				// 1.4、字符串型转布尔型
				.put(String.class, Boolean.class, StringToBoolean)//

				// 1.5、布尔型转数字型
				.put(Boolean.class, Byte.class, (Function<Boolean, Byte>) bool -> { return bool ? (byte) 1 : (byte) 0; })//
				.put(Boolean.class, Short.class, (Function<Boolean, Short>) bool -> { return bool ? (short) 1 : (short) 0; })//
				.put(Boolean.class, Integer.class, (Function<Boolean, Integer>) bool -> { return bool ? 1 : 0; })//
				.put(Boolean.class, Long.class, (Function<Boolean, Long>) bool -> { return bool ? 1L : 0L; })//
				.put(Boolean.class, Float.class, (Function<Boolean, Float>) bool -> { return bool ? 1f : 0f; })//
				.put(Boolean.class, Double.class, (Function<Boolean, Double>) bool -> { return bool ? 1d : 0d; })//
		;
	}

	// =================================================== 2、字符型 =================================================== //
	static {
		converters
				// 2.1、布尔型转字符型
				.put(Boolean.class, Character.class, (Function<Boolean, Character>) bool -> { return bool ? (char) 1 : (char) 0; })//

				// 2.2、字符型转字符型
				.put(Character.class, Character.class, SAME)//

				// 2.3、数字型转字符型
				.put(Byte.class, Character.class, NumberToCharacter)//
				.put(Short.class, Character.class, NumberToCharacter)//
				.put(Integer.class, Character.class, NumberToCharacter)//
				.put(Long.class, Character.class, NumberToCharacter)//
				.put(Float.class, Character.class, NumberToCharacter)//
				.put(Double.class, Character.class, NumberToCharacter)//

				// 2.4、字符串型转字符型
				.put(String.class, Character.class, (Function<String, Character>) str -> { return "".equals(str) ? (char) 0 : str.charAt(0); })//

				// 2.5、字符型转数字型
				.put(Character.class, Byte.class, (Function<Character, Byte>) c -> { return new Integer(c).byteValue(); })//
				.put(Character.class, Short.class, (Function<Character, Short>) c -> { return new Integer(c).shortValue(); })//
				.put(Character.class, Integer.class, (Function<Character, Integer>) c -> { return new Integer(c); })//
				.put(Character.class, Long.class, (Function<Character, Long>) c -> { return new Integer(c).longValue(); })//
				.put(Character.class, Float.class, (Function<Character, Float>) c -> { return new Integer(c).floatValue(); })//
				.put(Character.class, Double.class, (Function<Character, Double>) c -> { return new Integer(c).doubleValue(); })//
		;
	}

	// =================================================== 3、数字型互转 =================================================== //
	static {
		converters
				// 3.1、Byte
				.put(Byte.class, Byte.class, SAME)//
				.put(Byte.class, Short.class, (Function<Byte, Short>) n -> { return n.shortValue(); })//
				.put(Byte.class, Integer.class, (Function<Byte, Integer>) n -> { return n.intValue(); })//
				.put(Byte.class, Long.class, (Function<Byte, Long>) n -> { return n.longValue(); })//
				.put(Byte.class, Float.class, (Function<Byte, Float>) n -> { return n.floatValue(); })//
				.put(Byte.class, Double.class, (Function<Byte, Double>) n -> { return n.doubleValue(); })//

				// 3.2、Short
				.put(Short.class, Byte.class, (Function<Short, Byte>) n -> { return KNumberUtils.checkRange(n, Byte.MIN_VALUE, Byte.MAX_VALUE).byteValue(); })//
				.put(Short.class, Short.class, SAME)//
				.put(Short.class, Integer.class, (Function<Short, Integer>) n -> { return n.intValue(); })//
				.put(Short.class, Long.class, (Function<Short, Long>) n -> { return n.longValue(); })//
				.put(Short.class, Float.class, (Function<Short, Float>) n -> { return n.floatValue(); })//
				.put(Short.class, Double.class, (Function<Short, Double>) n -> { return n.doubleValue(); })//

				// 3.3、Integer
				.put(Integer.class, Byte.class, (Function<Integer, Byte>) n -> { return KNumberUtils.checkRange(n, Byte.MIN_VALUE, Byte.MAX_VALUE).byteValue(); })//
				.put(Integer.class, Short.class, (Function<Integer, Short>) n -> { return KNumberUtils.checkRange(n, Short.MIN_VALUE, Short.MAX_VALUE).shortValue(); })//
				.put(Integer.class, Integer.class, SAME)//
				.put(Integer.class, Long.class, (Function<Integer, Long>) n -> { return n.longValue(); })//
				.put(Integer.class, Float.class, (Function<Integer, Float>) n -> { return KNumberUtils.checkRange(n, Float.MIN_VALUE, Float.MAX_VALUE).floatValue(); })//
				.put(Integer.class, Double.class, (Function<Integer, Double>) n -> { return n.doubleValue(); })//

				// 3.4、Long
				.put(Long.class, Byte.class, (Function<Long, Byte>) n -> { return KNumberUtils.checkRange(n, Byte.MIN_VALUE, Byte.MAX_VALUE).byteValue(); })//
				.put(Long.class, Short.class, (Function<Long, Short>) n -> { return KNumberUtils.checkRange(n, Short.MIN_VALUE, Short.MAX_VALUE).shortValue(); })//
				.put(Long.class, Integer.class, (Function<Long, Integer>) n -> { return KNumberUtils.checkRange(n, Integer.MIN_VALUE, Integer.MAX_VALUE).intValue(); })//
				.put(Long.class, Long.class, SAME)//
				.put(Long.class, Float.class, (Function<Long, Float>) n -> { return KNumberUtils.checkRange(n, Float.MIN_VALUE, Float.MAX_VALUE).floatValue(); })//
				.put(Long.class, Double.class, (Function<Long, Double>) n -> { return KNumberUtils.checkRange(n, Double.MIN_VALUE, Double.MAX_VALUE).doubleValue(); })//

				// 3.5、Float
				.put(Float.class, Byte.class, (Function<Float, Byte>) n -> { return KNumberUtils.checkRange(n, Byte.MIN_VALUE, Byte.MAX_VALUE).byteValue(); })//
				.put(Float.class, Short.class, (Function<Float, Short>) n -> { return KNumberUtils.checkRange(n, Short.MIN_VALUE, Short.MAX_VALUE).shortValue(); })//
				.put(Float.class, Integer.class, (Function<Float, Integer>) n -> { return KNumberUtils.checkRange(n, Integer.MIN_VALUE, Integer.MAX_VALUE).intValue(); })//
				.put(Float.class, Long.class, (Function<Float, Long>) n -> { return KNumberUtils.checkRange(n, Long.MIN_VALUE, Long.MAX_VALUE).longValue(); })//
				.put(Float.class, Float.class, SAME)//
				.put(Float.class, Double.class, (Function<Float, Double>) n -> { return n.doubleValue(); })//

				// 3.6、Double
				.put(Double.class, Byte.class, (Function<Double, Byte>) n -> { return KNumberUtils.checkRange(n, Byte.MIN_VALUE, Byte.MAX_VALUE).byteValue(); })//
				.put(Double.class, Short.class, (Function<Double, Short>) n -> { return KNumberUtils.checkRange(n, Short.MIN_VALUE, Short.MAX_VALUE).shortValue(); })//
				.put(Double.class, Integer.class, (Function<Double, Integer>) n -> { return KNumberUtils.checkRange(n, Integer.MIN_VALUE, Integer.MAX_VALUE).intValue(); })//
				.put(Double.class, Long.class, (Function<Double, Long>) n -> { return KNumberUtils.checkRange(n, Long.MIN_VALUE, Long.MAX_VALUE).longValue(); })//
				.put(Double.class, Float.class, (Function<Double, Float>) n -> { return KNumberUtils.checkRange(n, Float.MIN_VALUE, Float.MAX_VALUE).floatValue(); })//
				.put(Double.class, Double.class, SAME)//
		;
	}

	// =================================================== 4、转字符串型 =================================================== //
	static {
		converters
				// 4.1、布尔型转字符串型
				.put(Boolean.class, String.class, (Function<Boolean, String>) str -> { return String.valueOf(str); })//

				// 4.2、字符型转字符串型
				.put(Character.class, String.class, (Function<Character, String>) str -> { return String.valueOf(str); })//

				// 4.3、数字型转字符串型
				.put(Byte.class, String.class, (Function<Byte, String>) str -> { return String.valueOf(str); })//
				.put(Short.class, String.class, (Function<Short, String>) str -> { return String.valueOf(str); })//
				.put(Integer.class, String.class, (Function<Integer, String>) str -> { return String.valueOf(str); })//
				.put(Long.class, String.class, (Function<Long, String>) str -> { return String.valueOf(str); })//
				.put(Float.class, String.class, (Function<Float, String>) str -> { return String.valueOf(str); })//
				.put(Double.class, String.class, (Function<Double, String>) str -> { return String.valueOf(str); })//

				// 4.4、字符串型转字符串型
				.put(String.class, String.class, SAME)//

				// 4.5、字符串型转数字型
				.put(String.class, Byte.class, (Function<String, Byte>) str -> { return KNumberUtils.checkRange(str, Byte.MIN_VALUE, Byte.MAX_VALUE).byteValue(); })//
				.put(String.class, Short.class, (Function<String, Short>) str -> { return KNumberUtils.checkRange(str, Short.MIN_VALUE, Short.MAX_VALUE).shortValue(); })//
				.put(String.class, Integer.class, (Function<String, Integer>) str -> { return KNumberUtils.checkRange(str, Integer.MIN_VALUE, Integer.MAX_VALUE).intValue(); })//
				.put(String.class, Long.class, (Function<String, Long>) str -> { return KNumberUtils.checkRange(str, Long.MIN_VALUE, Long.MAX_VALUE).longValue(); })//
				.put(String.class, Float.class, (Function<String, Float>) str -> { return KNumberUtils.checkRange(str, Float.MIN_VALUE, Float.MAX_VALUE).floatValue(); })//
				.put(String.class, Double.class, (Function<String, Double>) str -> { return KNumberUtils.checkRange(str, Double.MIN_VALUE, Double.MAX_VALUE).doubleValue(); })//
		;
	}

	// =================================================== 5、常用类型实现 =================================================== //
	static {
		converters

				// 5.1、日期类型互转
				.put(Date.class, Date.class, (Function<Date, Date>) date -> { return new Date(date.getTime()); })//

				// 5.2、日期类型与Long互转
				.put(Long.class, Date.class, (Function<Long, Date>) timestamp -> { return new Date(timestamp); })//
				.put(Date.class, Long.class, (Function<Date, Long>) date -> { return date.getTime(); })//

				// 5.3、日期类型与字符串互转
				.put(String.class, Date.class, (Function<String, Date>) str -> { return KDateTimeUtils.toDate(str, null); })//
				.put(Date.class, String.class, (Function<Date, String>) date -> { return KDateTimeUtils.toString(date, null); })//
		;
	}

}
